package com.koelo.kiss.re.interpreter.java.hotswap;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class ClassReloader
    extends ClassLoader {
	
	private String[] classpath;

    public ClassReloader(ClassLoader parent, String[] classpath) {
           
    	super(parent);
    	this.classpath = classpath;
    }
    
    private File getFile(String filename) {
    	
    	File file = new File(filename);
		for (String path: this.classpath) {
	    	file = new File(path + File.separatorChar + filename);
	    	if (file.exists()) {
	    		return file;
	    	}
		}
    	return file;
    	
    }
   
    private byte[] loadClassData(String filename)
    	throws IOException {

        // Create a file object relative to directory provided
        File f = getFile(filename);
        if (f != null) {
	        // Get size of class file
	        int size = (int)f.length();
	        // Reserve space to read
	        byte buff[] = new byte[size];
	        // Get stream to read from
	        FileInputStream fis = new FileInputStream(f);
	        DataInputStream dis = new DataInputStream (fis);
	        // Read in data
	        dis.readFully(buff);
	        // close stream
	        dis.close();
	        // return data
	        return buff;
        }
        throw new IOException("File not found " + filename);
    }

    @Override
    public Class<?> loadClass(String name, boolean reload)
    	throws ClassNotFoundException {

        Class<?> clazz = findLoadedClass(name);
        if (clazz == null) {
            try {
            	clazz = findSystemClass(name);
            } catch (Exception ex) {
            	//throw new ClassNotFoundException(ex.getMessage(), ex);
            }
        }
        if (clazz == null || reload == true) {
            String filename = name.replace ('.', File.separatorChar) + ".class";
            try {
                byte[] classData = loadClassData(filename);
                return defineClass(name, classData, 0, classData.length);
            } catch (IOException ex) {
            	throw new ClassNotFoundException(ex.getMessage(), ex);
            }
        }
        return clazz;
    }

    @Override
    public Class<?> loadClass(String name)
    	throws ClassNotFoundException {

    	return this.loadClass(name, false);
    }
} 